package maa.dao.h2;

import maa.action.ActionException;
import maa.dao.DAOException;
import maa.dao.DAOManager;
import maa.dao.DAOCommand;
import maa.dao.GroupDAO;
import maa.entity.Course;
import maa.entity.Group;
import maa.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class GroupDAOimpl implements DAOCommand, GroupDAO {
    private Connection connection;
    private final Logger logger = LoggerFactory.getLogger(GroupDAOimpl.class);
    private final String ALL_COURSES = "Select distinct courseid from client_subscription";
    private final String FIND_ALL = "Select clientid from client_subscription where courseid = ?";
    private final String MENTOR_COURSES = "Select courseid from courses where mentor = ?";

    public GroupDAOimpl() {
    }

    public GroupDAOimpl(Connection connection) {
        this.connection = connection;
    }

    public List<Group> findGroupsByMentor(UUID mentorID) throws DAOException {
        List<UUID> courseList = new ArrayList<>();
        List<Group> groups = new ArrayList<>();
        Group group = new Group();
        if (connection != null) {
            PreparedStatement preparedStatement = null;
            try {
                preparedStatement = connection.prepareStatement(MENTOR_COURSES);
                preparedStatement.setObject(1, mentorID);
                ResultSet set = preparedStatement.executeQuery();
                courseList = createCourseList(set);
                preparedStatement = connection.prepareStatement(FIND_ALL);
                for (UUID uuid : courseList) {
                    preparedStatement.setObject(1, uuid);
                    ResultSet resultSet = preparedStatement.executeQuery();
                    group = createEntity(uuid,resultSet);
                    groups.add(group);
                }
            } catch (SQLException e) {
                logger.error("Could not find all groups " + e.getMessage());
                throw new DAOException(e.getMessage());
            } finally {
                if (preparedStatement != null) {
                    close(preparedStatement);
                }
            }
        } else {
            throw new DAOException("No connection available");
        }
        logger.debug("Extracted all groups from database");
        return groups;
    }

    public List<Group> findAll() throws DAOException {
        List<UUID> courseList = new ArrayList<>();
        List<Group> groups = new ArrayList<>();
        Group group = new Group();
        if (connection != null) {
            PreparedStatement preparedStatement = null;
            try {
                preparedStatement = connection.prepareStatement(ALL_COURSES);
                ResultSet set = preparedStatement.executeQuery();
                courseList = createCourseList(set);
                preparedStatement = connection.prepareStatement(FIND_ALL);
                for (UUID uuid : courseList) {
                    preparedStatement.setObject(1, uuid);
                    ResultSet resultSet = preparedStatement.executeQuery();
                    group = createEntity(uuid,resultSet);
                    groups.add(group);
                }
            } catch (SQLException e) {
                logger.error("Could not find all groups " + e.getMessage());
                throw new DAOException(e.getMessage());
            } finally {
                if (preparedStatement != null) {
                    close(preparedStatement);
                }
            }
        } else {
            throw new DAOException("No connection available");
        }
        logger.debug("Extracted all groups from database");
        return groups;
    }

    public List<UUID> createCourseList(ResultSet set) throws SQLException {
        List<UUID> list = new ArrayList<>();
        while (set.next()) {
            UUID uuid = (UUID) set.getObject("courseid");
            list.add(uuid);
        }
        return list;
    }

    public Group createEntity(UUID uuid, ResultSet set) throws SQLException, DAOException {
        CourseDAOimpl courseDAO = new CourseDAOimpl(connection);
        UserDAOimpl userDAO = new UserDAOimpl(connection);
        Group group = new Group();
        List<UUID> uuidList = new ArrayList<>();
        while (set.next()) {
            UUID id = (UUID) set.getObject("clientid");
            uuidList.add(id);
        }
        Course course = courseDAO.findById(uuid);
        List<User> users = userDAO.findUsersById(uuidList);
        group.setUserList(users);
        group.setCourse(course);
        return group;
    }

    public void close(PreparedStatement statement) {
        try {
            statement.close();
        } catch (SQLException e) {
            logger.error(e.getMessage());
        }
    }

    @Override
    public Object execute(DAOManager daoManager) throws ActionException {
        return new Object();
    }
}
